﻿using CqCore.Commands;
using CqCore.Exception;
using CqCore.Logging;
using CqCore.Redis;
using Microsoft.Extensions.Options;
using SuperShopInfrastructure.Extensions;
using SuperShopInfrastructure.Models.Order;
using SuperShopInfrastructure.Models.Ship;
using SuperShopInfrastructure.Static;
using SuperShopInfrastructure.Weixin.Options;
using SuperShopInfrastructure.Weixin.Services;
using SuperShopRepository;
using SuperShopService.IServices;
using System;
using System.Collections.Generic;
using System.Data;
using System.Linq;
using System.Net.Http;
using System.Text;
using System.Threading.Tasks;
using UploadService.Option;

namespace SuperShopService.Services
{
    public class OrderService : IOrderService
    {
        private readonly IRedisService redisService;
        private readonly OrderRepository orderRepository;
        private readonly ILogRecorder<OrderService> logRecorder;
        private readonly ImageServiceOption imageServiceOption;
        private readonly IShopAppService shopAppService;
        private readonly WeiXinHelper weiXinHelper;
        private readonly IProductService productService;
        private readonly IMarketingService marketingService;
        private readonly IShopCartService shopCartService;
        private readonly WxConfigOption wxConfigOption;
        private readonly ISetService setService;
        private static object LockData = new object();

        public OrderService(
            IRedisService redisService,
            OrderRepository orderRepository,
            ILogRecorder<OrderService> logRecorder,
            IOptions<ImageServiceOption> options,
            IShopAppService shopAppService,
            WeiXinHelper weiXinHelper,
            IProductService productService,
            IMarketingService marketingService,
            IShopCartService shopCartService,
            ISetService setService,
            IOptions<WxConfigOption> wx_options)
        {
            this.redisService = redisService;
            this.orderRepository = orderRepository;
            this.logRecorder = logRecorder;
            this.imageServiceOption = options.Value;
            this.shopAppService = shopAppService;
            this.weiXinHelper = weiXinHelper;
            this.productService = productService;
            this.marketingService = marketingService;
            this.shopCartService = shopCartService;
            this.wxConfigOption = wx_options.Value;
            this.setService = setService;

        }

        public async Task<CommandResult<decimal>> CountShipAmount(CountShipAmountCommand command)
        {
            var shopAppModel = await shopAppService.GetShopAppModel(command.Spid.ToInt());
            if (shopAppModel == null)
                return CommandResult<decimal>.Failure("获取店铺模型出错");

            //读取每个商品的运费模板模型，并赋值
            command.Products.ForEach((item) =>
            {
                item.ShippingTemplateModel = setService.GetShippingTemplateModel(item.ShippingTemplateId).Result;
            });
            //检测是否有模板的配送省份，不包括收货人省份
            foreach (var item in command.Products)
            {
                if (!item.ShipAllProvinceIds.Contains(command.ProvinceCode))
                {
                    return CommandResult<decimal>.Failure("商品:" + item.ProductName + ",不参与邮件,请联系店家！");
                }
            }

            //取店铺的满额包邮设置模型
            var fullSetModel = await marketingService.GetSetModel(ToolManager.DecryptParms(shopAppModel.ShopAdminId).ToInt());
            var res = GetShipAmount(command, fullSetModel);
            return CommandResult<decimal>.Success(res);
        }

        private decimal GetShipAmount(CountShipAmountCommand command, FullSetViewModel fullSetModel)
        {
            if (fullSetModel.OptionStatus == 1)
            {
                //开启了满额包邮
                //是否满足金额
                if (fullSetModel.Amount <= command.TotalProductAmount)
                {
                    //配送地区是否在包邮范围
                    if (!fullSetModel.NotHasProvinceIdList.Contains(command.ProvinceCode))
                    {
                        //在包邮范围
                        //判断商品是否全部在包邮范围,如果都在范围，0运费返回，不都在，将包邮的商品从计算运费商品集合中删掉
                        if (IsExistProduct(fullSetModel.NotHasProductIdList, command.Products.Select(p => p.ProductId).ToList()))
                        {
                            //全部在包邮范围
                            return 0;
                        }
                        else
                        {
                            //部分结算商品在不包邮得商品中
                            //将包邮的商品从计算运费商品集合中删掉
                            var _tempList = new List<CountShipItem>();
                            command.Products.ForEach((item) =>
                            {
                                if (fullSetModel.NotHasProductIdList.Contains(item.ProductId))
                                {
                                    _tempList.Add(item);
                                }
                            });
                            command.Products = _tempList;
                        }
                    }

                }
            }
            var _tml = new List<CountShipItem>();
            //去掉模板包邮的商品，首重或者首件为0
            command.Products.ForEach((p) =>
            {
                //运费模板，根据发送地区不同有多个子模板，找出当前收货人地区的子模板
                var tm = p.ShippingTemplateModel.Items.Where(i => i.ProvinceIdList.Contains(command.ProvinceCode)).FirstOrDefault();
                if (tm.FirstAmount > 0)
                    _tml.Add(p);
            });
            command.Products = _tml;
            if (command.Products.Count == 0)//说明全部走的包邮模板
                return 0;

            //到了这一步，过滤了满额包邮情况，过滤了包邮模板商品，剩下的都是走运费模板，要计算了
            //算法：首重/首件最大值的模板的商品，先正常计算运费，剩下的模板的商品，只按照续件/续重计算，求和。
            var maxShipT = command.Products.OrderByDescending(p => p.CurrentShipItem.FirstAmount).FirstOrDefault();//找出运费子模板首最大的那个商品模型
            //取出走当前模板的商品模型
            var _maxProductList = command.Products.Where(p => p.ShippingTemplateId == maxShipT.ShippingTemplateId).ToList();
            //计算这个模板的商品集合一共的运费
            var maxProductShipAmount = CountAmount(_maxProductList, 1);
            var _otherProductList = command.Products.Where(p => p.ShippingTemplateId != maxShipT.ShippingTemplateId).ToList();
            if (_otherProductList.Count == 0)
                return maxProductShipAmount;
            var otherProductShipAmount = CountAmount(_otherProductList, 2);
            return maxProductShipAmount + otherProductShipAmount;
        }

        private decimal CountAmount(List<CountShipItem> list, int type)
        {
            var res = 0m;
            if (type == 1)
            {
                var ship = list[0].CurrentShipItem;
                //正常计算,先算首再算续
                //这里正常计算的，一定是同一个运费模板，单个计算，会导致续的费用变多，所以先求总重或者总件，一起计算
                if (list[0].ShippingTemplateModel.ChargType == 1)
                {
                    //按件数

                    var totalCount = list.Sum(p => p.SaleNum);//求所有商品的总件数
                    if (totalCount > ship.FirstValue)
                    {
                        //超过首件数量了
                        res = ship.FirstAmount + Math.Ceiling((totalCount - ship.FirstValue) / decimal.Parse(ship.NextValue.ToString())) * ship.NextAmount;
                    }
                    else
                    {
                        res = ship.FirstAmount;
                    }
                }
                else if (list[0].ShippingTemplateModel.ChargType == 2)
                {
                    //按重量
                    var totalWeight = list.Sum(p => p.SaleNum * p.Weight);//求总重量
                    if (totalWeight > ship.FirstValue)
                    {
                        res = ship.FirstAmount + Math.Ceiling(Convert.ToDecimal((totalWeight - ship.FirstValue)) / ship.NextValue) * ship.NextAmount;
                    }
                    else
                    {
                        res = ship.FirstAmount;
                    }

                }
            }
            else
            {
                //只计算续。
                //先根据模板ID分组，循环组
                IEnumerable<IGrouping<int, CountShipItem>> pGroup = list.GroupBy(p => p.ShippingTemplateId);
                foreach (var ps in pGroup)
                {
                    var _products = ps.ToList();
                    var _ship = _products[0].CurrentShipItem;
                    if (_products[0].ShippingTemplateModel.ChargType == 1)
                    {
                        //按件数
                        var _totalCount = _products.Sum(p => p.SaleNum);//求所有商品的总件数
                                                                        //超过首件数量了
                        res += Math.Ceiling(_totalCount / decimal.Parse(_ship.NextValue.ToString())) * _ship.NextAmount;
                    }
                    else
                    {
                        //按重量
                        var _totalWeight = _products.Sum(p => p.SaleNum * p.Weight);//求总重量
                        res += Math.Ceiling(Convert.ToDecimal(_totalWeight) / _ship.NextValue) * _ship.NextAmount;

                    }

                }
            }
            return res;
        }



        /// <summary>
        /// 判断商品是否全部在包邮范围
        /// </summary>
        /// <param name="list1">满额包邮不参与得商品集合</param>
        /// <param name="list2">结算商品集合</param>
        /// <returns></returns>
        private bool IsExistProduct(List<string> list1, List<string> list2)
        {
            var result = true;
            foreach (var item in list2)
            {
                if (list1.Contains(item))
                {
                    result = false;
                    break;
                }
            }
            return result;
        }

        public async Task<CreateOrderResultViewModel> GetPayData(string userid, string orderno)
        {
            var res = await redisService.Get<CreateOrderResultViewModel>(orderno + userid);
            return res;
        }

        public async Task<WxPayData> WxCallBack(StringBuilder stringBuilder)
        {
            //转换数据格式并验证签名
            WxPayData data = new WxPayData();
            try
            {
                data.FromXml(stringBuilder.ToString());
                //错误时没有签名
                if (data.IsSet("return_code") && data.GetValue("return_code").ToString() == "SUCCESS" && data.IsSet("sign") && data.GetValue("sign").ToString() != "")
                {
                    string appid = data.GetValue("appid").ToString();
                    string paykey = await shopAppService.GetPayKeyByAppid(appid);
                    if (appid != null)
                    {
                        //获取接收到的签名
                        string return_sign = data.GetValue("sign").ToString();
                        //在本地计算新的签名
                        string cal_sign = data.MakeSign(paykey);
                        if (cal_sign == return_sign)
                        {
                            //更新订单状态
                            string out_trade_no = data.GetValue("out_trade_no").ToString();
                            //重复调用验证
                            lock (LockData)
                            {

                                if (redisService.Get<string>(out_trade_no).GetAwaiter().GetResult() != null)
                                {
                                    logRecorder.Error(new EventData()
                                    {
                                        Type = "WxCallBack",
                                        Message = "微信支付回调发生了频繁重复调用！订单号" + out_trade_no
                                    });
                                    return null;
                                }
                                else
                                {
                                    //将当前订单号写入缓存
                                    redisService.Set(out_trade_no, out_trade_no, DateTime.Now.AddMinutes(15)).GetAwaiter().GetResult();
                                }
                            }
                            string transaction_id = data.GetValue("transaction_id").ToString();
                            string result_code = data.GetValue("result_code").ToString();
                            string err_code = data.IsSet("err_code") ? data.GetValue("err_code").ToString() : string.Empty;
                            string time_end = data.GetValue("time_end").ToString();
                            float total_fee = 0; Int64 paytime; int status = 0;
                            float.TryParse(data.GetValue("total_fee").ToString(), out total_fee);
                            Int64.TryParse(time_end, out paytime);
                            if (result_code == "SUCCESS")
                            {
                                status = 1;
                            }
                            else if (result_code == "FAIL")
                            {
                                status = 2;
                            }
                            else
                            {
                                logRecorder.Error(new EventData()
                                {
                                    Type = "WxCallBack",
                                    Message = "微信回调业务结果错误返回信息和业务结果",
                                    Labels = {
                                        ["data"] = stringBuilder.ToString(),
                                        ["result_code"] = result_code
                                    }
                                });

                            }

                            logRecorder.Info(new EventData()
                            {
                                Type = "WxCallBack",
                                Message = "微信回调金额数据",
                                Labels = {
                                        ["out_trade_no"] = out_trade_no,
                                        ["status"] = status.ToString(),
                                        ["total_fee"] = (total_fee / 100).ToString()
                                    }
                            });

                            if (status == 1 || status == 2)
                            {
                                //存储过程操作
                                var ret = await orderRepository.Program_WxNotice_Cart(out_trade_no, status, (total_fee / 100), transaction_id);
                                //记日志，参数，返回值
                                logRecorder.Info(new EventData()
                                {
                                    Type = "WxCallBack",
                                    Message = "微信回调更改状态返回",
                                    Labels = {
                                        ["ret"] = ret.ToString()
                                    }
                                });

                            }
                            WxPayData res = new WxPayData();
                            res.SetValue("return_code", "SUCCESS");
                            res.SetValue("return_msg", "OK");
                            return res;

                        }
                        else
                        {
                            logRecorder.Error(new EventData()
                            {
                                Type = "WxCallBack",
                                Message = "微信回调签名认证失败",
                                Labels = {
                                        ["builder"] = stringBuilder.ToString(),
                                        ["return_sign"] = return_sign,
                                        ["loaction_sign"] = cal_sign
                                    }
                            });

                            WxPayData res = new WxPayData();
                            res.SetValue("return_code", "FAIL");
                            res.SetValue("return_msg", "签名失败");
                            return res;
                        }
                    }
                    else
                    {
                        logRecorder.Error(new EventData()
                        {
                            Type = "WxCallBack",
                            Message = "微信回调商户不存在"
                        });
                        WxPayData res = new WxPayData();
                        res.SetValue("return_code", "FAIL");
                        res.SetValue("return_msg", "商户不存在");
                        return res;
                    }
                }
                else
                {
                    logRecorder.Error(new EventData()
                    {
                        Type = "WxCallBack",
                        Message = "参数格式校验错误"
                    });
                    WxPayData res = new WxPayData();
                    res.SetValue("return_code", "FAIL");
                    res.SetValue("return_msg", "参数格式校验错误");
                    return res;
                }
            }
            catch (Exception ex)
            {
                logRecorder.Error(new EventData()
                {
                    Type = "WxCallBack",
                    Message = "微信回调异常",
                    Labels = {
                        ["ex"] = ex.InnerException.GetBaseException().Message,
                        ["StackTrace"] = ex.StackTrace
                    }
                });

                WxPayData res = new WxPayData();
                res.SetValue("return_code", "FAIL");
                res.SetValue("return_msg", "回调数据异常");
                return res;
            }
        }

        public async Task<CommandResult<CreateOrderResultViewModel>> CreateOrder(CreateOrderCommand command)
        {
            var shopAppModel = await shopAppService.GetShopAppModel(command.Spid.ToInt());
            if (shopAppModel == null)
                return CommandResult<CreateOrderResultViewModel>.Failure("获取店铺模型出错");
            //deleted
            foreach (var item in command.CreateOrder_ProductItems)
            {
                var _productid = ToolManager.DecryptParms(item.ProductId);
                if (_productid == null)
                    return CommandResult<CreateOrderResultViewModel>.Failure("非法参数");
                item.ProductId = _productid;
            }

            var skuids = string.Join(",", command.CreateOrder_ProductItems.Select(p => p.Product_SkuId.ToString()).ToArray());

            //获取需要检测的商品相关数据
            var checkList = await productService.GetCreateOrder_CheckItemList(skuids);
            command.CreateOrder_ProductItems.ForEach((item) =>
            {
                item.CreaterOrder_CheckItem = checkList.FirstOrDefault(i => i.ProductSkuId == item.Product_SkuId);
            });
            //验证SKU
            foreach (var item in command.CreateOrder_ProductItems)
            {
                var _productName = item.CreaterOrder_CheckItem.ProductName + " " + item.CreaterOrder_CheckItem.ProppetyCombineName;
                if (item.SaleNum > item.CreaterOrder_CheckItem.StockNum)
                    return CommandResult<CreateOrderResultViewModel>.Failure("商品-" + _productName + " 库存不足");
                if (item.CreaterOrder_CheckItem.IsDel == 1)
                    return CommandResult<CreateOrderResultViewModel>.Failure("商品-" + _productName + " 已删除过期");
                if (item.CreaterOrder_CheckItem.Product_OptionStatus != 1)
                    return CommandResult<CreateOrderResultViewModel>.Failure("商品" + _productName + " 已下架或删除");
                if (item.CreaterOrder_CheckItem.Product_IsDel == 1)
                    return CommandResult<CreateOrderResultViewModel>.Failure("商品" + _productName + " 已删除");
            }

            //验证金额
            var _totalProductAmount = 0m;//商品总金额
            command.CreateOrder_ProductItems.ForEach((item) =>
            {
                _totalProductAmount += item.SaleNum * item.CreaterOrder_CheckItem.SallPrice;
            });
            //优惠券使用情况
            var _couponAmount = 0.0m;
            if (command.CouponId > 0)
            {

                var couponModel = await marketingService.GetUserCoupon(command.UserId.ToInt(), command.CouponId);
                if (couponModel.CouponId == 0)
                    return CommandResult<CreateOrderResultViewModel>.Failure("优惠非法参数");
                if (couponModel.CouponType == 1)
                {
                    //满减券
                    if (_totalProductAmount < couponModel.MinOrderAmount)
                        return CommandResult<CreateOrderResultViewModel>.Failure("满减优惠券数据异常");
                    else
                        _couponAmount = couponModel.DelAmount;
                }
                else if (couponModel.CouponType == 2)
                {
                    //折扣券
                    _couponAmount = decimal.Round(((100 - couponModel.Discount) / 100m) * _totalProductAmount, 2);
                    //测试如果是1分钱得话
                    if (_couponAmount < 0.01m)
                        _couponAmount = 0.01m;
                }
                _totalProductAmount -= _couponAmount;
            }
            var _totalAmount = _totalProductAmount + command.ShipAmount;
            if (_totalAmount != command.ToalAmount)
                return CommandResult<CreateOrderResultViewModel>.Failure("计算金额非法");

            //临时将本地购物车数据，插入购物车表，在下单存储过程重读取
            if (!await shopCartService.CreateOrderInsert(command))
                return CommandResult<CreateOrderResultViewModel>.Failure("购物车数据异常");

            command.ProductAmount = _totalProductAmount;
            command.CouponAmount = _couponAmount;

            var createOrderResult = await Program_CreateOrder_Cart(command);//deleted
            if (!createOrderResult.IsSuccess)
                return CommandResult<CreateOrderResultViewModel>.Failure(createOrderResult.FailureReason);
            CreateOrderResultViewModel resultmodel = new CreateOrderResultViewModel();
            resultmodel.OrderID = createOrderResult.GetData().OrderID;

            //微信统一下单
            WxPayData wxd = WeiXinCreateOrder(createOrderResult.GetData());
            if (wxd == null)
                return CommandResult<CreateOrderResultViewModel>.Failure("微信统一下单失败");

            var payParamater = new OrderPayResultModel();
            payParamater.AppId = wxd.GetValue("appId").ToString();
            payParamater.TimeStamp = wxd.GetValue("timeStamp").ToString();
            payParamater.NonceStr = wxd.GetValue("nonceStr").ToString();
            payParamater.Package = wxd.GetValue("package").ToString();
            payParamater.SignType = wxd.GetValue("signType").ToString();
            payParamater.PaySign = wxd.GetValue("paySign").ToString();
            payParamater.Payorderno = wxd.GetValue("payorderno").ToString();
            payParamater.Orderno = wxd.GetValue("orderno").ToString();

            resultmodel.PayParamater = payParamater;
            //存储当前订单的拉起微信支付的模型
            await redisService.Set<CreateOrderResultViewModel>(payParamater.Orderno + command.UserId, resultmodel, DateTime.Now.AddMinutes(15));

            return CommandResult<CreateOrderResultViewModel>.Success(resultmodel);

        }

        private async Task<CommandResult<Program_CreateOrder_CartResult>> Program_CreateOrder_Cart(CreateOrderCommand command)
        {
            var createOrderResult = await orderRepository.Program_CreateOrder_Cart(command);
            if (createOrderResult.Item2 != 1)
            {
                switch (createOrderResult.Item2)
                {
                    case 2:
                        return CommandResult<Program_CreateOrder_CartResult>.Failure("用户不存在");
                    case 3:
                        return CommandResult<Program_CreateOrder_CartResult>.Failure("地址不存在");
                    case 4:
                        return CommandResult<Program_CreateOrder_CartResult>.Failure("商户不存在");
                    case 5:
                        return CommandResult<Program_CreateOrder_CartResult>.Failure("执行事务出错");
                    default:
                        return CommandResult<Program_CreateOrder_CartResult>.Failure("下单异常");

                }
            }
            if (DataManager.CheckDs(createOrderResult.Item1, 1) && DataManager.CheckHasRow(createOrderResult.Item1.Tables[0]))
            {
                var res = new Program_CreateOrder_CartResult();
                DataRow dr = createOrderResult.Item1.Tables[0].Rows[0];
                res.Appid = dr["Appid"].ToString();
                res.OrderNumber = dr["OrderNumber"].ToString();
                res.Paykey = dr["Paykey"].ToString();
                res.Mch_id = dr["Mch_id"].ToString();
                res.Openid = dr["Openid"].ToString();
                res.TotalFee = double.Parse(dr["TotalFee"].ToString());
                res.OrderID = int.Parse(dr["OrderID"].ToString());
                return CommandResult<Program_CreateOrder_CartResult>.Success(res);
            }
            return CommandResult<Program_CreateOrder_CartResult>.Failure("下单未知异常");
        }

        private WxPayData WeiXinCreateOrder(Program_CreateOrder_CartResult model)
        {
            logRecorder.Info(new EventData()
            {
                Type = "WeiXinCreateOrder",
                Message = "统一下单参数",
                Labels = {
                    ["parms"] = model.ToJson()
                }
            });
            //string notifyurl = "";//deleted
            //if (model.AppType == 1)
            //{
            //    notifyurl = ConfigSettings.Instance.WxCallBackUrl;
            //}
            //else if (model.AppType == 2)
            //{
            //    notifyurl = ConfigSettings.Instance.WxCallBackUrl_H5;
            //}

            string paykey = model.Paykey;
            string time_start = DateTime.Now.ToString("yyyyMMddHHmmss");
            string time_expire = DateTime.Now.AddMinutes(10).ToString("yyyyMMddHHmmss");
            //统一下单
            WxPayData data = new WxPayData();
            data.SetValue("appid", model.Appid);//公众账号ID
            data.SetValue("mch_id", model.Mch_id);//商户号
            data.SetValue("nonce_str", ToolManager.GenerateNonceStr());//随机字符串
            data.SetValue("body", "正在卖的商品");//商品描述
                                            //data.SetValue("attach", "test");//附加数据
            data.SetValue("out_trade_no", model.OrderNumber);//商户订单号
            data.SetValue("total_fee", (int)Math.Round(model.TotalFee * 100));//总金额 单位分
            data.SetValue("time_start", time_start);
            data.SetValue("time_expire", time_expire);
            //data.SetValue("goods_tag", "test");//商品标记 代金券或立减优惠功能的参数
            data.SetValue("trade_type", "JSAPI");
            data.SetValue("openid", model.Openid);
            data.SetValue("notify_url", wxConfigOption.WxCallBackUrl);//异步通知url
            data.SetValue("spbill_create_ip", "");//终端ip
            data.SetValue("sign", data.MakeSign(model.Paykey));
            string xml = data.ToXml();
            string response = weiXinHelper.Post(xml, wxConfigOption.WxPayUrl, false, 10);

            logRecorder.Info(new EventData()
            {
                Type = "WeiXinCreateOrder",
                Message = "统一下单参数返回数据",
                Labels = {
                    ["parms"] = response
                }
            });
            WxPayData result = new WxPayData();
            result.FromXml(response);
            //签名验证
            // 错误时没有签名
            if (result.IsSet("return_code") && result.GetValue("return_code").ToString() == "SUCCESS" && result.IsSet("sign") && result.GetValue("sign").ToString() != "")
            {
                //获取接收到的签名
                string return_sign = result.GetValue("sign").ToString();
                //在本地计算新的签名
                string cal_sign = result.MakeSign(paykey);
                if (cal_sign == return_sign)
                {
                    if (result.IsSet("appid") && result.IsSet("prepay_id") && result.GetValue("prepay_id").ToString() != "")
                    {
                        string prepay_id = result.GetValue("prepay_id").ToString();
                        WxPayData jsApiParam = new WxPayData();
                        jsApiParam.SetValue("appId", result.GetValue("appid"));
                        jsApiParam.SetValue("timeStamp", ToolManager.ConvertDateTimeInt(DateTime.Now));
                        jsApiParam.SetValue("nonceStr", ToolManager.GenerateNonceStr());
                        jsApiParam.SetValue("package", "prepay_id=" + prepay_id);
                        jsApiParam.SetValue("signType", "MD5");
                        jsApiParam.SetValue("paySign", jsApiParam.MakeSign(paykey));
                        //
                        //jsApiParam.SetValue("payorderno", prepay_id);
                        jsApiParam.SetValue("payorderno", model.OrderNumber);
                        jsApiParam.SetValue("orderno", model.OrderNumber);
                        return jsApiParam;
                    }
                    else
                    {
                        return null;
                    }
                }
                else
                {
                    logRecorder.Info(new EventData()
                    {
                        Type = "WeiXinCreateOrder",
                        Message = "微信下单返回后验证签名失败",
                        Labels = {
                            ["orderNumber"] = model.OrderNumber,
                            ["return_sign"] = return_sign,
                            ["loaction_sign"] = cal_sign
                        }
                    });
                    return null;
                }
            }
            else
            {
                if (result.IsSet("return_msg") && result.GetValue("return_msg").ToString() != "")
                {
                    logRecorder.Info(new EventData()
                    {
                        Type = "WeiXinCreateOrder",
                        Message = "微信支付预处理失败",
                        Labels = {
                            ["orderNumber"] = model.OrderNumber,
                            ["return_msg"] = result.GetValue("return_msg").ToString()
                        }
                    });
                    return null;
                }
                else
                {
                    return null;
                }
            }
        }

        public async Task<bool> ServiceOrder(int orderid, int userid)
        {
            return await orderRepository.ServiceOrder(orderid, userid);
        }

        public async Task<List<OrderListViewModel>> GetOrderList(QueryOrderListCriteria criteria)
        {
            var queryList = new List<OrderListViewModel>();
            var ds = await orderRepository.GetOrderList(criteria);
            if (DataManager.CheckDs(ds, 1) && DataManager.CheckHasRow(ds.Tables[0]))
            {
                foreach (DataRow dr in ds.Tables[0].Rows)
                {
                    queryList.Add(new OrderListViewModel()
                    {
                        OrderID = Convert.ToInt32(dr["Id"]),
                        ProductNum = Convert.ToInt32(dr["ProductNum"]),
                        OrderStatus = Convert.ToInt32(dr["OrderStatus"]),
                        BuyNum = Convert.ToInt32(dr["BuyNum"]),
                        OrderNo = dr["OrderNo"].ToString(),
                        ProductId = SecretClass.EncryptQueryString(dr["ProductId"].ToString()),

                        Said = SecretClass.EncryptQueryString(dr["ShopAdminId"].ToString()),
                        ProductName = dr["ProductName"].ToString(),
                        ProppetyCombineName = dr["ProppetyCombineName"].ToString(),
                        ImagePath = imageServiceOption.ImgHost + dr["ImagePath"].ToString(),
                        RealityAmount = Convert.ToDecimal(dr["RealityAmount"]),
                        CommentId = Convert.ToInt32(dr["CommentId"]),
                        SalePrice = Convert.ToDecimal(dr["SalePrice"])
                    });
                }
            }
            return queryList;
        }

        public async Task<OrderDetail_InfoViewModel> GetDetail(int orderid)
        {
            //由于订单除了状态，都是静态数据。所有把静态数据，存进redis
            var orderModel = await redisService.GetOrSet<OrderDetail_InfoViewModel>("GetDetail_" + orderid, async () =>
            {
                var res = await GetDetail_Db(orderid);
                return res;
            }, 1);
            if (orderModel == null)
                throw new Exception($"读取订单失败_{BadRequstKey.Key}");
            int orderstatus = await GetOrderStatus(orderid);
            orderModel.OrderStatus = orderstatus;
            return orderModel;
        }

        public async Task<OrderDetail_InfoViewModel> GetDetail_Db(int orderid)
        {

            var ds = await orderRepository.GetDetail(orderid);
            if (DataManager.CheckDs(ds, 2) && DataManager.CheckHasRow(ds.Tables[0]) && DataManager.CheckHasRow(ds.Tables[1]))
            {
                var res = new OrderDetail_InfoViewModel();
                DataRow dr = ds.Tables[0].Rows[0];
                res.ConsigneeName = dr["ConsigneeName"].ToString();
                res.ConsigneePhone = dr["ConsigneePhone"].ToString();
                res.Address = dr["Address"].ToString();
                res.OrderNo = dr["OrderNo"].ToString();
                res.Remark = dr["Remark"].ToString();
                res.OrderAmount = Convert.ToDecimal(dr["OrderAmount"]);
                res.CouponName = dr["CouponName"].ToString();
                res.CreateTime = Convert.ToDateTime(dr["CreateTime"]).ToString("yyyy-MM-dd HH:mm:ss");
                res.CommentId = Convert.ToInt32(dr["CommentId"]);
                res.PayTime = dr["PayTime"].ToString();
                res.RealityAmount = Convert.ToDecimal(dr["RealityAmount"]);
                res.CouponDelAmount = Convert.ToDecimal(dr["CouponDelAmount"]);
                res.ShippingAmount = Convert.ToDecimal(dr["ShippingAmount"]);
                res.OrderID = Convert.ToInt32(dr["Id"]);
                res.DeliveryName = dr["DeliveryName"].ToString();
                res.DeliveryNo = dr["DeliveryNo"].ToString();
                foreach (DataRow dr_detail in ds.Tables[1].Rows)
                {
                    res.Products.Add(new OrderDetail_ProductItem()
                    {
                        ProductId = SecretClass.EncryptQueryString(dr_detail["ProductId"].ToString()),
                        ProductName = dr_detail["ProductName"].ToString(),
                        ProppetyCombineName = dr_detail["ProppetyCombineName"].ToString(),
                        ImagePath = imageServiceOption.ImgHost + dr_detail["ImagePath"].ToString(),
                        BuyNum = Convert.ToInt32(dr_detail["BuyNum"]),
                        SalePrice = Convert.ToDecimal(dr_detail["SalePrice"])
                    });
                }
                return res;
            }
            return null;
        }

        public async Task<int> GetOrderStatus(int orderId)
        {
            var res = 0;
            var ds = await orderRepository.GetOrderStatus(orderId);
            if (DataManager.CheckDs(ds, 1) && DataManager.CheckHasRow(ds.Tables[0]))
            {
                res = Convert.ToInt32(ds.Tables[0].Rows[0]["OrderStatus"]);
            }
            return res;
        }
    }
}
